package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"regexp"
	"strings"
)

const (
	PATH = "/home/justin/Videos/voa/"
)

func main() {
	urls := "http://www.51voa.com/Learning_English_Videos_1.html"
	resp, _ := http.Get(urls)
	defer resp.Body.Close()
	input, _ := ioutil.ReadAll(resp.Body)
	//input, _ := ioutil.ReadFile("text.txt")
	content := string(input)
	r := regexp.MustCompile(`第 .*? 页</div>`)
	tmpStr := r.FindString(content)
	r = regexp.MustCompile(`<a href=".*?">`)
	videosLink := r.FindAllString(tmpStr, -1)
	for i := 0; i < len(videosLink); i++ {
		videosLink[i] = strings.Replace(videosLink[i], `<a href="`, "", -1)
		videosLink[i] = strings.Replace(videosLink[i], `">`, "", -1)
		urls = "http://www.51voa.com/" + videosLink[i]
		resp, _ = http.Get(urls)
		defer resp.Body.Close()
		input, _ = ioutil.ReadAll(resp.Body)
		//input, _ = ioutil.ReadFile("text.txt")
		content = string(input)
		r = regexp.MustCompile(`<li> <a href=".*?" target=_blank>`)
		videosSubLink := r.FindAllString(content, -1)
		count := len(videosSubLink)
		chanNum := 5
		if chanNum > count {
			chanNum = count
		}
		execChans := make(chan bool, chanNum)
		doneChans := make(chan bool, 1)
		for j := 0; j < count; j++ {
			tmpStr = videosSubLink[j]
			tmpStr = strings.Replace(tmpStr, `<li> <a href="`, "http://www.51voa.com/", -1)
			tmpStr = strings.Replace(tmpStr, `" target=_blank>`, "", -1)
			go voa(tmpStr, execChans, doneChans)
		}
		for j := 0; j < count; j++ {
			msg := <-doneChans // 完成一个，同时获取下一个任务
			<-execChans        // 紧接着读取下一个任务，类是于beanstalkd的任务分发机制
			if msg {           // 获取失败时，打印该网址失败。
				fmt.Printf("No. %d:%d/%d is succeed\n", i+1, j+1, count)
			} else {
				fmt.Printf("No. %d:%d/%d is  failure\n", i+1, j+1, count)
			}
		}
		close(doneChans) // 关闭完成信号
		close(execChans) // 关闭执行信号
		fmt.Println("done!")
	}
}

//http://stream.51voa.com/201503/sri-lankan-american-gives-back-to-her-home-country.mp4
func downloadVideo(urls string) string {
	//	resp, _ := http.Get(urls)
	//	defer resp.Body.Close()
	name := strings.Split(urls, "/")
	videoName := name[len(name)-1]
	//	file, _ := os.Create(PATH + name[len(name)-1])
	//	defer file.Close()
	//	io.Copy(file, resp.Body)
	cmd := exec.Command("wget", "-O", PATH+videoName, urls)
	cmd.Output()
	return videoName
}

func downloadText(urls string, name string) bool {
	resp, _ := http.Get(urls)
	defer resp.Body.Close()
	input, _ := ioutil.ReadAll(resp.Body)
	content := string(input)
	file, _ := os.Create(PATH + name + ".txt")
	defer file.Close()
	r := regexp.MustCompile(`<a id="EnPage" href=".*?" target=_blank></a>`)
	if r.MatchString(content) {
		tmpStr := r.FindString(content)
		tmpStr = strings.Replace(tmpStr, `<a id="EnPage" href="`, "http://www.51voa.com/VOA_Special_English/", -1)
		tmpStr = strings.Replace(tmpStr, `" target=_blank></a>`, "", -1)
		resp, _ = http.Get(tmpStr)
		defer resp.Body.Close()
		input, _ = ioutil.ReadAll(resp.Body)
		content = string(input)
	}
	r = regexp.MustCompile(`(?s)<div id="content">.*?/div>`)
	content = r.FindString(content)
	//fmt.Println(content)
	r = regexp.MustCompile(`<.*?>`)
	content = r.ReplaceAllString(content, "")
	file.WriteString(content)
	return true
}

func voa(urls string, execChans chan bool, doneChans chan bool) {
	execChans <- true // 放在函数的开始处，用来阻塞执行，如果通道里的数量超过设定数量，在没有读取完成前，不会运行
	isOk := false
	name := ""
	defer func() {
		doneChans <- isOk
	}()
	resp, _ := http.Get(urls)
	defer resp.Body.Close()
	input, _ := ioutil.ReadAll(resp.Body)
	//input, _ := ioutil.ReadFile("videos.txt")
	content := string(input)
	r := regexp.MustCompile(`<div id="RelatedBox"><a href=.*?>视频下载`)
	if r.MatchString(content) {
		tmpStr := r.FindString(content)
		tmpStr = strings.Replace(tmpStr, `<div id="RelatedBox"><a href=`, "", -1)
		tmpStr = strings.Replace(tmpStr, ">视频下载", "", -1)
		name = downloadVideo(tmpStr)
	}
	r = regexp.MustCompile(`<div id="RelatedBox"><a href=.*?>相关文本及翻译`)
	if r.MatchString(content) {
		tmpStr := r.FindString(content)
		tmpStr = strings.Replace(tmpStr, `<div id="RelatedBox"><a href=`, "http://www.51voa.com", -1)
		tmpStr = strings.Replace(tmpStr, ">相关文本及翻译", "", -1)
		downloadText(tmpStr, name)
	}
	isOk = true
	return
}
